﻿using Core.Framework.Model.Common;
using Core.Framework.Model.WebSockets;
using Core.Framework.Redis;
using Core.Framework.Redis.Queue_Helper;
using Core.Framework.Util;
using Core.Service.TaskHandle;
using Microsoft.AspNetCore.Builder;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Core.Framework.Loger;

namespace Core.Middleware.WebSockets
{
    public static class UseWebSocketConfig 
    {
        /// <summary>
        /// ws 中间键
        /// </summary>
        /// <typeparam name="TWebSocket">WebSocket工厂</typeparam>
        /// <typeparam name="WebSocketMessage">WebSocket消息工厂</typeparam>
        /// <param name="applicationBuilder"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseWebSocketsMiddleware(this IApplicationBuilder applicationBuilder )
        {
            // 初始化消息监听器
            TaskHandleFactory.Initialization(true);

            // 如果未Null 结束操作
            if (TaskHandleFactory.MQMsgHandlers.Where(a => a.Template == WebSokcetHelper.WebSocketMidWare.Template).Count() == 0)
                new Exception($"使用 'UseWebSocketsMiddleware' 需要注册:Listener > {WebSokcetHelper.WebSocketMidWare.Template}");

            return applicationBuilder.UseMiddleware<WebSokcetHelper.WebSocketMidWare>();
        }

        /// <summary>
        /// 队列处理
        /// [QueueTimedLoop]
        /// </summary>
        /// <param name="applicationBuilder"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseQueueLoop(this IApplicationBuilder applicationBuilder)
        {
            // redis 链接预热
            var preloading = RedisConnectionHelper.Instance;

            // 实例redis
            var redis = new RedisHelper();

            // 注册当前客户机服务[集群]
            {
                // 初始化消息监听器
                TaskHandleFactory.Initialization(true);

                // 如果未Null 结束操作
                if (TaskHandleFactory.MQMsgHandlers.Count == 0)
                    return applicationBuilder;

                var temps = new List<Listener_Template>();

                // 初始化服务集合
                foreach (var handler in TaskHandleFactory.MQMsgHandlers)
                    temps.Add(new Listener_Template { template = handler.Template, Subscription = null });

                redis.HashSet(RedisQueueHelperParameter.QueueService, RedisQueueHelperParameter.ServiceClinet, temps);

                // 订阅当前服务客户机
                redis.Subscribe(RedisQueueHelperParameter.ServiceClinet, (channle, msg) =>
                {
                    RedisQueueHelper.SortedPush(RedisQueueHelperParameter.Queue, msg);
                });
            }

            // 实例数量
            var length = CoreStartupHelper.GetConfigValue("QueueTimedLoop:length").ToInt(1);

            // 休眠时间
            var sleeps = CoreStartupHelper.GetConfigValue("QueueTimedLoop:parameter:sleep").ToInt(200);

            // 并发线程数
            var threadLength =  CoreStartupHelper.GetConfigValue("QueueTimedLoop:parameter:threadLength").ToInt(10);

            // 注册服务
            while (length > 0)
            {
                Thread.Sleep(sleeps / length);
                length--;
                Task.Run(() => {
                    new Consumer().TimedLoop(threadLength, sleeps);
                });
            }

            return applicationBuilder;
        }

        /// <summary>
        /// 队列未处理消息
        /// </summary>
        /// <param name="applicationBuilder"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseQueueUntreatedLoop(this IApplicationBuilder applicationBuilder, int sleep = 1000)
        {

            Task.Run(() => 
            {
                while (true)
                {
                    Thread.Sleep(sleep);

                    try
                    {
                        var values
                            = RedisQueueHelper.SortedPop(RedisQueueHelperParameter.UntreatedQueue);

                        if (values.Length > 0)
                        {
                            foreach (var item in values)
                            {
                                var entity
                                    = ((string)item).TryToEntity<QueryMessage>();

                                new QueueMsg().DoDispatch(entity);
                            }
                        }
                    }
                    catch(Exception e)
                    {
                        RunningLoger.Error($"QueueUntreatedLoop:{e.Message}");
                    }
                }
            });

            return applicationBuilder;
        }
    }
}
